with Ada.Exceptions;
with Ada.Unchecked_Conversion;
with Ada.Strings.Fixed;

package body win32api_interface is
  function Get_Error_Message(Error_ID : in Win32.DWORD) return string is
    use Ada.Strings.Fixed;
    length_dw  : Win32.DWORD;
    length_int : Integer;

    Max_Length_int : constant Integer := 512;
    Max_Length_dw  : Win32.DWORD;
    type tError is new string(1..Max_Length_int);
    Error: aliased tError;
    type pError is access all tError;
    pE: pError:= Error'access;
    function pError_to_Address is new
      Ada.Unchecked_Conversion(source => pError, target => Win32.PCHAR);

    LANG_NEUTRAL_SUBLANG_SYS_DEFAULT : constant Win32.DWORD := 16#0800#;
  begin
    Max_Length_dw := Win32.DWORD(Max_Length_int);
    length_dw:=
      Win32.Winbase.FormatMessage(Win32.Winbase.FORMAT_MESSAGE_FROM_SYSTEM,
                                  System.Null_Address, Error_ID,
                                  LANG_NEUTRAL_SUBLANG_SYS_DEFAULT,
                                  pError_to_Address(pE), Max_Length_dw);
    length_int := Integer(length_dw);
    return Head(string(Error), length_int);
  end Get_Error_Message;

  procedure Put_Error(Operation : in String; Error_ID : in Win32.DWORD) is
    Message : string := Get_Error_Message(Error_ID);
  begin
    --Put_Line(Operation&": #"&Win32.DWORD'Image(Error_ID)&": "&Message);
    Ada.Exceptions.Raise_Exception(Win32_Error'Identity,Operation&": #"&
                                   Win32.DWORD'Image(Error_ID)&": "&Message);
  end Put_Error;

  procedure Report_Error(Operation : in String) is
    Error_ID : Win32.DWORD;
  begin
    Error_ID := Get_Last_Error;
    Put_Error(Operation, Error_ID);
  end Report_Error;

  procedure Report_Error_Thr(Operation : in String; Error_ID : in Win32.DWORD) is
  begin
    Put_Error(Operation, Error_ID);
  end Report_Error_Thr;
end win32api_interface;
